Skip to content

[#633] Unify user upsert to fix concurrent race condition#650

Merged
realproject7 merged 2 commits intomainfrom
task/633-upsert-race-fix
Mar 30, 2026
Merged

[#633] Unify user upsert to fix concurrent race condition#650
realproject7 merged 2 commits intomainfrom
task/633-upsert-race-fix

Conversation

@realproject7
Copy link
Copy Markdown
Owner

Summary

  • New lib/user-upsert.ts: Shared findUserByWallet() and upsertUser() helpers with consistent conflict resolution — always updates by row id, re-queries on 23505 conflict to find the correct row.
  • register-by-wallet: Replaced inline lookup + INSERT-then-catch-UPDATE with shared helpers.
  • onboard: Same replacement — both routes now use identical upsert logic.

Previously, concurrent calls used different conflict keys (fid vs primary_address) which could corrupt rows with mixed data.

Fixes #633
Tracks realproject7/agent-os#313

Test plan

  • Concurrent register + onboard calls don't corrupt or duplicate user rows
  • FID users, wallet-only users, and agent users all upsert correctly
  • 5-min cooldown still enforced on onboard route
  • Build passes

🤖 Generated with Claude Code

Created shared upsertUser() helper in lib/user-upsert.ts that both
register-by-wallet and onboard routes now use. Key changes:

- Shared findUserByWallet() for consistent user lookup
- Always update by row id when existing user is known
- On 23505 conflict (concurrent insert), re-query to get row id
  then update by id — both routes now use identical resolution
- Eliminates divergent fid-vs-primary_address conflict keys

Fixes #633

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 30, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
plotlink Ignored Ignored Mar 30, 2026 7:10pm

Request Review

Copy link
Copy Markdown
Collaborator

@project7-interns project7-interns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: REQUEST CHANGES

Summary

The shared upsert refactor is directionally right, but the new lookup helper regresses agent-user handling.

Findings

  • [high] findUserByWallet() only checks verified_addresses and primary_address, so both routes now miss existing rows that are keyed by agent_wallet / agent_owner.
    • File: lib/user-upsert.ts:16
    • Suggestion: Reuse the full wallet lookup behavior from getUserFromDB() (including agent_wallet and agent_owner), or otherwise extend findUserByWallet() so agent users participate in the same cooldown and id-based upsert path.

Decision

Requesting changes because the issue explicitly requires preserving correct handling for agent users, and the new helper can return null for those rows, which breaks the conflict-retry/update path in both routes.

Aligns findUserByWallet() with the full lookup chain in getUserFromDB()
so agent users are found correctly during upsert conflict resolution.

Addresses T2a review feedback on PR #650.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@project7-interns project7-interns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: APPROVE

Summary

The shared upsert refactor now preserves the broader wallet lookup behavior for agent users while unifying both routes onto the same id-based conflict resolution path.

Findings

  • None.

Decision

Approving on code review. The earlier agent-user regression is addressed; the remaining CI checks are still running, but they do not block the review verdict.

@realproject7 realproject7 merged commit 157bfbf into main Mar 30, 2026
5 checks passed
@realproject7 realproject7 deleted the task/633-upsert-race-fix branch March 30, 2026 19:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix register-by-wallet vs onboard upsert race condition

2 participants